
package com.mind.customer.template;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.mind.customer.template.TemplateParser.VARIABLE_PATTERN;

// TemplateEngine.java
@Log4j2
@Component
public class TemplateEngine {

    public List<String> render(String template, JsonNode data) {
        // 1. 解析模板
        TemplateVariables variables = TemplateParser.parseTemplate(template);

        // 2. 处理普通变量
        List<ValueRecord> records = expandVariables(variables.getVariables(), data);

        // 3. 处理表格
        List<String> tableValues = new ArrayList<>();
        for (List<TableColumn> table : variables.getTables()) {
            tableValues.add(TableGenerator.generateMarkdownTable(data, table));
        }

        // 4. 组合最终结果
        return renderRecords(template, records, tableValues);
    }

    public List<String> render(String template, JsonNode data, String prefix) throws JsonProcessingException {
        // 1. 解析模板
        TemplateVariables variables = TemplateParser.parseTemplate(template, prefix);

        // 2. 处理普通变量
        List<ValueRecord> records = expandVariables(variables.getVariables(), data);

        // 3. 处理表格
        List<String> tableValues = new ArrayList<>();
        for (List<TableColumn> table : variables.getTables()) {
            tableValues.add(TableGenerator.generateMarkdownTable(data, table));
        }

        // 4. 组合最终结果
        return renderRecords(template, records, tableValues);
    }

    private List<ValueRecord> expandVariables(
            List<TemplateVariable> variables,
            JsonNode data
    ) {
        List<ValueRecord> records = new ArrayList<>();
        int maxSize = 1;
        Map<TemplateVariable, List<String>> valueMap = new HashMap<>();

        for (TemplateVariable var : variables) {
            // 使用实际路径（不带前缀）获取值
            List<String> values = JsonPathResolver.resolveValue(data, var.getPath());
            valueMap.put(var, values);
            maxSize = Math.max(maxSize, values.size());
        }

        for (int i = 0; i < maxSize; i++) {
            ValueRecord record = new ValueRecord();
            for (TemplateVariable var : variables) {
                List<String> values = valueMap.get(var);
                String value = values.size() > i ? values.get(i) : "";

                // 关键修改：使用原始表达式作为键
                record.addValue(var.getOriginalExpression(), value);
            }
            records.add(record);
        }

        return records;
    }


    /*  private String renderRecords(
              String template,
              List<ValueRecord> records,
              List<String> tables
      ) {
          if (records.isEmpty()) {
              return replaceTables(template, tables);
          }

          StringBuilder result = new StringBuilder();
          int index = 1;

          for (ValueRecord record : records) {
              String recordText = template;

              // 替换变量 - 使用原始表达式进行替换
              for (Map.Entry<String, String> entry : record.getValues().entrySet()) {
                  String pattern = "\\$\\{" + Pattern.quote(entry.getKey()) + "\\}";
                  recordText = recordText.replaceAll(pattern, entry.getValue());
              }

              // 替换表格占位符
              recordText = replaceTables(recordText, tables);

              // 添加行号
              result.append(index++).append(". ").append(recordText).append("\n");
          }

          return result.toString();
      }
  */
    private List<String> renderRecords(
            String template,
            List<ValueRecord> records,
            List<String> tables
    ) {
        List<String> dataStr = new ArrayList<String>();
        // 没有记录时直接替换表格
        if (records.isEmpty()) {
            dataStr.add(replaceTables(template, tables));
            return dataStr;
        }

        // 检查模板中变量表达式的数量
        int variableCount = getVariableCount(template);
        boolean isSingleVariable = variableCount == 1;

        StringBuilder result = new StringBuilder();

        if (isSingleVariable) {
            // 单个变量的渲染方式（带行号）
//            int index = 1;
            for (ValueRecord record : records) {
                String recordText = processRecord(template, record, tables);
                dataStr.add(recordText);
//                result.append(index++).append(". ").append(recordText).append("\n");
            }
        } else {
            // 多个变量的渲染方式（无行号，数组值拼接）
            ValueRecord mergedRecord = mergeRecords(records);
            String mergedText = processRecord(template, mergedRecord, tables);
            result.append(mergedText);
            dataStr.add(result.toString());
        }

        return dataStr;
    }

    // 获取模板中的变量表达式数量
    private int getVariableCount(String template) {
        Matcher matcher = VARIABLE_PATTERN.matcher(template);
        int count = 0;
        while (matcher.find()) {
            String expression = matcher.group(1);
//            if (!expression.startsWith("tab:")) { // 排除表格变量
            count++;
//            }
        }
        return count;
    }

    // 合并多条记录的处理
// 合并多条记录的处理
    private ValueRecord mergeRecords(List<ValueRecord> records) {
        ValueRecord merged = new ValueRecord();

        // 对于每个变量表达式，收集所有值
        Set<String> expressions = new HashSet<>();
        for (ValueRecord record : records) {
            expressions.addAll(record.getValues().keySet());
        }

        for (String expression : expressions) {
            List<String> values = new ArrayList<>();

            // 收集所有记录中该表达式的值
            for (ValueRecord record : records) {
                String value = record.getValues().get(expression);
                if (value != null) {
                    values.add(value);
                }
            }

            // 根据值数量决定格式
            if (values.size() > 1) {
                merged.addValue(expression, "[" + String.join(",", values) + "]");
            } else if (!values.isEmpty()) {
                merged.addValue(expression, values.get(0));
            }
        }

        return merged;
    }

    // 处理单条记录的变量替换
    private String processRecord(String template, ValueRecord record, List<String> tables) {
        String result = template;

        // 替换变量
        for (Map.Entry<String, String> entry : record.getValues().entrySet()) {
            String pattern = "\\$\\{" + Pattern.quote(entry.getKey()) + "\\}";
            result = result.replaceAll(pattern, entry.getValue());
        }

        // 替换表格占位符
        result = replaceTables(result, tables);

        return result;
    }

    private String replaceTables(String text, List<String> tables) {
        Matcher matcher = TemplateParser.TABLE_PATTERN.matcher(text);
        StringBuffer result = new StringBuffer();
        int tableIndex = 0;

        while (matcher.find()) {
            matcher.appendReplacement(result,
                    tableIndex < tables.size() ? tables.get(tableIndex++) : "");
        }
        matcher.appendTail(result);

        return result.toString();
    }

    private static class ValueRecord {
        private Map<String, String> values = new HashMap<>();

        public void addValue(String originalExpression, String value) {
            values.put(originalExpression, value);
        }

        public Map<String, String> getValues() {
            return values;
        }

        public boolean contains(String key) {
            return values.containsKey(key);
        }

        // 支持在已有值的基础上更新值
        public void updateValue(String key, String value) {
            if (values.containsKey(key)) {
                values.put(key, value);
            }
        }
    }

    // 测试单一模版
    public static void test003() throws JsonProcessingException {
        String jsonData = """
                {
                  "Basic": {},
                  "Detail": {
                    "酒店结账单": [
                      {
                        "入住时间": "2025-05-30",
                        "姓名": "张三",
                        "账单抬头": "ABC"
                      },
                      {
                        "入住时间": "2025-05-31",
                        "姓名": "李四",
                        "账单抬头": "BDA"
                      }
                    ]
                  },
                  "Attachments": []
                }
                """;
        String template = """
                ###规则描述
                判断中间过程是否闭环,中间过程每个行程都的出发地都是上一个行程的到达地
                ###判断内容
                ${大模型测试.酒店结账单.账单抬头}
                """;
        JsonNode data = new ObjectMapper().readTree(jsonData);
        TemplateEngine engine = new TemplateEngine();
        JsonNode detail = data.get("Detail");
        List<String> render = engine.render(template, detail, "大模型测试.");
        System.out.println(template);
        System.out.println(render);
    }

    public static void test004() throws JsonProcessingException {
        String jsonData = """
                {
                  "Basic": {},
                  "Detail": {
                    "酒店结账单": [
                      {
                        "入住时间": "2025-05-30",
                        "姓名": "张三",
                        "账单抬头": "ABC"
                      },
                      {
                        "入住时间": "2025-05-31",
                        "姓名": "李四",
                        "账单抬头": "BDA"
                      }
                    ]
                  },
                  "Attachments": []
                }
                """;
        String template = """
                ###规则描述
                判断中间过程是否闭环,中间过程每个行程都的出发地都是上一个行程的到达地
                ###判断内容
                ${tab:大模型测试.酒店结账单.账单抬头,大模型测试.酒店结账单.姓名,大模型测试.酒店结账单.入住时间}
                """;
        JsonNode data = new ObjectMapper().readTree(jsonData);
        TemplateEngine engine = new TemplateEngine();
        JsonNode detail = data.get("Detail");
        List<String> render = engine.render(template, detail, "大模型测试.");
        System.out.println(template);
        System.out.println(render);
    }

    // 测试多模版
    public static void test002() throws JsonProcessingException {
        String jsonData = """
                {
                  "Basic": {},
                  "Detail": {
                    "酒店结账单": [
                      {
                        "入住时间": "2025-05-30",
                        "姓名": "张三",
                        "账单抬头": "ABC"
                      },
                      {
                        "入住时间": "2025-05-31",
                        "姓名": "李四",
                        "账单抬头": "BDA"
                      }
                    ]
                  },
                  "Attachments": []
                }
                """;
        String template = """
                ###规则描述
                判断中间过程是否闭环,中间过程每个行程都的出发地都是上一个行程的到达地
                ###判断内容
                ${大模型测试.酒店结账单.账单抬头}
                ${tab:大模型测试.酒店结账单.账单抬头,大模型测试.酒店结账单.姓名,大模型测试.酒店结账单.入住时间}
                """;
        JsonNode data = new ObjectMapper().readTree(jsonData);
        TemplateEngine engine = new TemplateEngine();
        JsonNode detail = data.get("Detail");
        List<String> render = engine.render(template, detail, "大模型测试.");
        System.out.println(template);
        System.out.println(render);
    }

    public static void test001() throws JsonProcessingException {
        String jsonData = """
                {
                  "a": {
                    "b": {
                      "b1": 1.3,
                      "b2": 2,
                      "b3": [
                        "张三"
                      ],
                      "b4": [{
                        "b41": "qwe",
                        "b42": "421"
                      },{
                        "b41": "qwe",
                        "b42": "421"
                      }
                      ]
                    },
                    "c": {
                      "d": "c1"
                    }
                  }
                }
                """;
        JsonNode data = new ObjectMapper().readTree(jsonData);
        TemplateEngine engine = new TemplateEngine();
        testSimp(data, engine);
        testArray(data, engine);
        testTable(data, engine);
    }

    public static void testTable(JsonNode data, TemplateEngine engine) {
        String template = "###判断规则 下面值是否相等 \n###判断内容\n测试表格值 ${tab:a.b.b4.b41,a.b.b4.b42|列2}";
        List<String> result = engine.render(template, data);
        System.out.println(result);
// 输出：
// 测试表格值
// | 列1 | 列2 |
// |-----|-----|
// | qwe | 421 |
// | asd | 123 |
    }


    // 数组展开
    public static void testArray(JsonNode data, TemplateEngine engine) throws JsonProcessingException {


        String template = "测试值 ${a.b.b3} 和 ${a.b.b4.b41}";
        List<String> result = engine.render(template, data);
        System.out.println(result);
// 输出：
// 1. 测试值 张三 和 qwe
// 2. 测试值 和 asd

    }

    // 输出：判断 1 和 c1 是否相等
    public static void testSimp(JsonNode data, TemplateEngine engine) throws JsonProcessingException {
        String template = "判断${a.b.b1} 和 ${a.c.d} 是否相等";


        List<String> result = engine.render(template, data);

        System.out.println(result);
    }
}
